package gui;


import information.Kaart;
import information.Pacman;
import information.Vakje;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;

import javax.swing.JFrame;

import processing.core.PApplet;
import util.Coordinaat;
import util.Richting;
import util.WindRichting;



public class GUI extends PApplet{
	
	private int maximaleRuimte;
	
	/**
	 * Creates a new GUI.
	 * 
	 * @throws	NullPointerException
	 * 			pacman == null
	 * @throws	NullPointerException
	 * 			kaart == null
	 */
	public GUI(Pacman pacman, Kaart kaart)
	{
		if(pacman == null)
			throw new NullPointerException();
		if(kaart == null)
			throw new NullPointerException();
		
		this.kaart = kaart;
		this.pacman = pacman;
		
		final JFrame f = new JFrame();
		f.add(this, BorderLayout.NORTH);
		init();
		f.setVisible(true);
		f.setSize(getSize());
		
		updateMaxRuimte(getPreferredSize());
		
		f.setResizable(true);
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		f.addComponentListener(new Resizer());
		addKeyListener(new keyListener());
		
		
	}
	
	private void updateMaxRuimte(Dimension preferredSize) {
		if(preferredSize.height < preferredSize.width)
			maximaleRuimte = preferredSize.height;
		else
			maximaleRuimte = preferredSize.width;
	}

	private Pacman getPacman()
	{
		return pacman;
	}
	
	private Pacman pacman;
	
	private Kaart getKaart()
	{
		return kaart;
	}
	
	private Kaart kaart;
	
	
	
	public void setup()
	{
		size(600, 600);
	}

	public void draw()
	{
		background(200,200,200);
		noStroke();
				
		paint();
	}
	

	public void paint()
	{
		Kaart kaart = getKaart();
		int minKolom = kaart.getMinimaalXCoordinaat();
		int maxKolom = kaart.getMaximaleXCoordinaat();
		int minRij = kaart.getMinimaalYCoordinaat();
		int maxRij = kaart.getMaximaleYCoordinaat();
		
		int aantalRijen = maxRij - minRij + 1;
		int aantalKolommen = maxKolom - minKolom + 1;
		int aantalLijnenInEenVakje = 8;
		int maximaalAantalLijnenKaart;
		if(aantalRijen >= aantalKolommen) {
			maximaalAantalLijnenKaart = (aantalLijnenInEenVakje+1)*aantalRijen + 1;
		}
		else {
			maximaalAantalLijnenKaart = (aantalLijnenInEenVakje+1)*aantalKolommen + 1;
		}
		int lijnBreedte = maximaleRuimte/maximaalAantalLijnenKaart;
		int vakBreedte = aantalLijnenInEenVakje*lijnBreedte;
		int vakVerschil = vakBreedte+lijnBreedte;
		
		tekenMuren(minKolom, maxKolom, minRij, maxRij, lijnBreedte, vakBreedte, vakVerschil);
		
		tekenPacman(minKolom, maxRij, minRij, lijnBreedte, vakBreedte, vakVerschil);
	}
	
	private void tekenPacman(int minKolom, int maxRij, int minRij, int lijnBreedte, int vakBreedte, int vakVerschil)
	{
		Coordinaat laatsteCoordPacman = getPacman().getPosition();
		
		if(laatsteCoordPacman == null)
			return;
		
		Vakje vakje = getKaart().getRauwVakjeOp(laatsteCoordPacman);
		
		fill(255,255,0);
		ellipse((laatsteCoordPacman.getX() - minKolom)*vakVerschil + lijnBreedte + (vakBreedte/2),
				(maxRij - laatsteCoordPacman.getY())*vakVerschil + lijnBreedte + (vakBreedte/2),
				vakBreedte - 2*lijnBreedte, vakBreedte - 2*lijnBreedte);
		fill(0);
		triangle((laatsteCoordPacman.getX() - minKolom)*vakVerschil + lijnBreedte + (vakBreedte/2),
				(maxRij - laatsteCoordPacman.getY())*vakVerschil + lijnBreedte + (vakBreedte/2),
				(laatsteCoordPacman.getX() - minKolom)*vakVerschil + lijnBreedte + (vakBreedte/2) - (vakBreedte/2),
				(maxRij - laatsteCoordPacman.getY())*vakVerschil + lijnBreedte + (vakBreedte/2) + (vakBreedte/2),
				(laatsteCoordPacman.getX() - minKolom)*vakVerschil + lijnBreedte + (vakBreedte/2) - (vakBreedte/2),
				(maxRij - laatsteCoordPacman.getY())*vakVerschil + lijnBreedte + (vakBreedte/2) - (vakBreedte/2));
	}
	
	/**
	 * 
	 */
	private void tekenMuren(int minKolom, int maxKolom, int minRij, int maxRij, int lijnBreedte, 
			int vakBreedte, int vakVerschil) {
		tekenGrensMuren(minKolom, maxKolom, minRij, maxRij, lijnBreedte, vakBreedte, vakVerschil);
		tekenMuurhoekpunten(minKolom, maxKolom, minRij, maxRij, lijnBreedte, vakVerschil);
	}
	
	/**
	 * 
	 */
	private void tekenMuurhoekpunten(int minKolom, int maxKolom, int minRij, int maxRij, int lijnBreedte, int vakVerschil) {
		// getYCoord() + maxRij*vakVerschil + lijnBreedte + (vakBreedte/2) + laatsteCoordPacman.getY()*vakVerschil,
		

		fill(0,24,157);
		
		for(int i=minKolom; i<= maxKolom + 1; i++) {
			for(int j=minRij; j<= maxRij + 1; j++) {
		    	rect((vakVerschil)*(i-minKolom),
		    			(maxRij - j + 1)*vakVerschil,
		    			lijnBreedte, lijnBreedte);
		    }
		}
	}

	/**
	 * 
	 */
	private void tekenGrensMuren(int minKolom, int maxKolom, int minRij, int maxRij, int lijnBreedte, int vakBreedte, int vakVerschil) {
				
		
	for(int i=minKolom; i<= maxKolom; i++)
		for(int j=minRij; j<= maxRij; j++)
	    {
	    	Vakje vakje = getKaart().getRauwVakjeOp(new Coordinaat(i, j));
	    	if(vakje != null)
	    	{
	    		
	    		fill(0);
	    		rect((vakVerschil)*(i-minKolom) + lijnBreedte/2,
		    			(maxRij - j)*vakVerschil + lijnBreedte/2,
		    			vakVerschil, vakVerschil);
	    		
		    	for(WindRichting w : WindRichting.values())
		    	{
		    		Coordinaat[] zuidCoords = new Coordinaat[4];
		    		// 0    1
		    		// 3    2
		    		zuidCoords[0] = new Coordinaat(-(vakBreedte/2),-(vakBreedte/2) - lijnBreedte);
		    		zuidCoords[1] = new Coordinaat(vakBreedte/2,-(vakBreedte/2) - lijnBreedte);
		    		zuidCoords[2] = new Coordinaat(vakBreedte/2,-(vakBreedte/2));
		    		zuidCoords[3] = new Coordinaat(-(vakBreedte/2),-(vakBreedte/2));
		    		
		    		Richting draaiNaar = w.richtingVanOrientatie(WindRichting.NOORD);
		    		for(int k = 0; k < 4; k++)
		    			zuidCoords[k] = zuidCoords[k].roteer(draaiNaar);
		    		Coordinaat linksboven = zuidCoords[0];
		    		for(int l = 1; l < 4; l++)
		    		{
		    			if(zuidCoords[l].getX() <= linksboven.getX() && zuidCoords[l].getY() <= linksboven.getY())
		    				linksboven = zuidCoords[l];
		    		}
		    		int xMuur;
		    		int yMuur;
		    		if(zuidCoords[0].getX() == zuidCoords[1].getX())
		    		{
		    			xMuur = lijnBreedte;
		    			yMuur = vakBreedte;
		    		}
		    		else 
		    		{
		    			xMuur = vakBreedte;
		    			yMuur = lijnBreedte;
		    		}
		    		
			    	if (vakje.getVakGrens(w).isMuur() == null){
			    		fill(255,255,102);}
			    	else if(vakje.getVakGrens(w).isMuur())
			    		fill(50,24,157);
			    	else
			    		continue;
			    		//getParent().fill(200,200,200);
//				    	if(WindRichting.ZUID == w)
			    	rect(lijnBreedte + vakBreedte/2 + linksboven.getX() + (vakVerschil)*(i-minKolom),
			    			(maxRij - j)*vakVerschil + lijnBreedte + vakBreedte/2 + linksboven.getY(),
			    			xMuur, yMuur);
		    		
		    	}
	    	}
	    }
	}
	
	private class Resizer implements ComponentListener {
		@Override
		public void componentShown(ComponentEvent arg0) {				
		}

		@Override
		public void componentResized(ComponentEvent arg0) {
			updateMaxRuimte(arg0.getComponent().getSize());
		}

		@Override
		public void componentMoved(ComponentEvent arg0) {
			
		}

		@Override
		public void componentHidden(ComponentEvent arg0) {
			
		}
	}

	private class keyListener implements KeyListener
	{

		@Override
		public void keyPressed(KeyEvent e) {
			if(e.getKeyCode() == UP)
				getPacman().move(WindRichting.NOORD);
			if(e.getKeyCode() == LEFT)
				getPacman().move(WindRichting.WEST);
			if(e.getKeyCode() == RIGHT)
				getPacman().move(WindRichting.OOST);
			if(e.getKeyCode() == DOWN)
				getPacman().move(WindRichting.ZUID);
		}

		@Override
		public void keyReleased(KeyEvent e) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void keyTyped(KeyEvent e) {
			// TODO Auto-generated method stub
			
		}
		
	}
}
